﻿using System;
using System.Collections.Generic;
using System.Linq;
using com.eforceglobal.crux.security.EncryptionAndHashing;
using com.eforceglobal.crux.security.EncryptionAndHashing.Enums;
using com.eforceglobal.crux.BusinessObjects;
using com.eforceglobal.crux.BusinessObjects.DatabaseQueries;

namespace com.eforceglobal.crux.BusinessFacades
{
    public class PasswordFacade
    {
        public void ResetPassword(int userid, string password, PasswordStorageType passwordstoragetype, int securityQuesId, string ans, int savedPasswordCount, bool isFeatureSupported)
        {
            string userPassword = password;
            if (passwordstoragetype == PasswordStorageType.hashed)
                userPassword = Hasher.GetHash(userPassword);
            Queries query = new Queries();
            User dbUser = query.GetUser(userid);
            dbUser.Password = userPassword;
            dbUser.PasswordChangedOn = DateTime.Now;
            dbUser.IsResetPasswordNeeded = false;
            dbUser.SecurityQuestionID = securityQuesId;
            dbUser.SecurityAnswer = ans;
            if(isFeatureSupported)
                SavePassword(dbUser, savedPasswordCount, query);
            query.SubmitChanges();
        }

        public void ResetPassword(int userid, string password, PasswordStorageType passwordstoragetype, int savedPasswordCount, bool isFeatureSupported)
        {
            string userPassword = password;
            if (passwordstoragetype == PasswordStorageType.hashed)
                userPassword = Hasher.GetHash(userPassword);
            Queries query = new Queries();
            User dbUser = query.GetUser(userid);
            dbUser.Password = userPassword;
            dbUser.PasswordChangedOn = DateTime.Now;
            dbUser.IsResetPasswordNeeded = dbUser.SecurityAnswer == null ? true : false;
            if(isFeatureSupported)
                SavePassword(dbUser, savedPasswordCount, query);
            query.SubmitChanges();
        }

        internal void SavePassword(User dbUser, int savedPasswordCount, Queries query)
        {
            List<ChangedPassword> changedPasswordList = new List<ChangedPassword>();
            changedPasswordList = query.GetChangedPasswordByUserID(dbUser.UserID).ToList();
            if (changedPasswordList.Count() >= savedPasswordCount)
            {
                changedPasswordList = changedPasswordList.OrderBy(c => c.PasswordChangedOn).ToList();
                changedPasswordList.Reverse();
                List<ChangedPassword> toBeDeletedList = new List<ChangedPassword>();
                for (int i = changedPasswordList.Count; i > savedPasswordCount - 1; i--)
                {
                    ChangedPassword password = changedPasswordList[i - 1];
                    toBeDeletedList.Add(password);
                }
                query.DeleteSavedPassword(toBeDeletedList);
                InsertChangedPassword(query, dbUser);
            }
            else
            {
                InsertChangedPassword(query, dbUser);
            }
        }

        private void InsertChangedPassword(Queries query, User dbUser)
        {
            ChangedPassword changedPassword = new ChangedPassword();
            changedPassword.Password = dbUser.Password;
            changedPassword.PasswordChangedOn = dbUser.PasswordChangedOn;
            changedPassword.UserID = dbUser.UserID;
            query.InsertPassword(changedPassword);
        }

        public void ResetPassword(string userName, string password, PasswordStorageType passwordstoragetype, int savedPasswordCount, bool isFeatureSupported)
        {
            string userPassword = password;
            if (passwordstoragetype == PasswordStorageType.hashed)
                userPassword = Hasher.GetHash(userPassword);
            Queries query = new Queries();
            User dbUser = query.GetUser(userName);
            dbUser.Password = userPassword;
            dbUser.PasswordChangedOn = DateTime.Now;
            dbUser.IsResetPasswordNeeded = false;
            if(isFeatureSupported)
                SavePassword(dbUser, savedPasswordCount, query);
            query.SubmitChanges();
        }

        public bool IsPasswordUsedBefore(string password, int userId, PasswordStorageType passwordStorageType, int savedPasswordCount)
        {
            Queries query = new Queries();
            if (passwordStorageType == PasswordStorageType.hashed)
                password = Hasher.GetHash(password);
            List<ChangedPassword> passwords = query.GetChangedPasswordByUserID(userId).ToList();
            passwords = passwords.OrderBy(c => c.PasswordChangedOn).ToList();
            if(passwords.Count > savedPasswordCount)
            {
                int count = passwords.Count - savedPasswordCount;
                passwords.RemoveRange(0, count);
            }
            if (passwords.Where(p => p.Password.Contains(password)).Count() > 0)
                return true;
            else
                return false;
        }

        public bool IsPasswordUsedBefore(string password, string userName, PasswordStorageType passwordStorageType, int savedPasswordCount)
        {
            Queries query = new Queries();
            User dbUser = query.GetUser(userName);
            return IsPasswordUsedBefore(password, dbUser.UserID, passwordStorageType, savedPasswordCount);
        }
    }
}
